// JORGE FERNANDO GOMEZ
// 1259371
// 189631
// LEC A1
// MARTIN MÜLLER
// D02
// YANG LIU


#ifndef GAMESTATE_H
#define GAMESTATE_H 1

#include <stdbool.h>

#define GAMESTATE_DEBUG     0

#define WORLD_WIDTH         640
#define WORLD_HEIGHT        480

#define MAXPOINTS 20

#define MAX_NAME            15
#define LAND_HASHT_SIZE     5
#define MAX_SHAPE_SEGMENTS  500

#define TIMESTEP_MICRO      50000.00
#define TIMESTEP_SEC        0.05
#define DEFAULT_ANGLE       10
#define PI                  acos(-1.0)

#define LEFT                -1
#define RIGHT               1
#define NEGATIVE            (-1) *
#define SCALE_FACTOR        2


/* World landscape struct. */
struct worldLandscape  {
    double dx[MAXPOINTS];
    double dy[MAXPOINTS];

    int drawCount;
};

typedef struct __landerLocation LanderLocationCoords;


/* Struct to hold the lander figure
 * segment points. */
struct __landerLocation {
    double x;
    double y;

    double dx;
    double dy;
};

typedef struct __landerFigure LanderFigure;


/* Struct LanderFigure will represent a lander object.
 *
 * It has the following members:
 *
 *      name            =>  Holds a string representing the lander's name.
 *                          Useful because I'm using a hash with string keys
 *                          to access each lander object.
 *
 *      side_length     =>  Represents the lander's base length.
 *
 *      x_offset
 *      y_offset        =>  Represent the amount of x-axis and y-axis units the
 *                          lander object figure should be shifted by before
 *                          drawing or before erasing.  Basically, it holds
 *                          the current lander position.
 *
 *      x_offset_old
 *      y_offset_old    =>  As x_offset and y_offset, but they hold the
 *                          previous values stored before applying the next
 *                          time step.
 *
 *      velocity_x
 *      velocity_y      =>  velocity_x and velocity_y, as the x,y-offsets,
 *                          hold the current lander velocity for both the
 *                          x and y axis.
 *
 *      thrust_x
 *      thrust_y        =>  As velocity_x and velocity_y, thrust_x, thrust_y
 *                          hold the current acceleration values resulting
 *                          from applying the thruster on a certain angle.
 *
 *      thrust_on       =>  This is a boolean value which holds true if
 *                          the thruster was applied during a time step,
 *                          or false if it wasn't.
 *
 *
 *      terminal_velocity
 *                      =>  terminal_velocity holds the estimated terminal
 *                          velocity for the lander depending on its starting
 *                          height.
 *
 *      orientation     =>  Holds the current lander orientation (angle).
 *                          90 degrees represent upright.
 *
 *      landerSegments  =>  This is an array of LanderLocationCoords which
 *                          hold two endpoints (x1, y1), (x2, y2) of a lander
 *                          segment.
 *
 *      segmentCount    =>  Holds the segment count for the lander figure. */

struct __landerFigure {
    char name[MAX_NAME];
    double side_length;

    double x_offset, y_offset;
    double x_offset_old, y_offset_old;

    double velocity_x;
    double velocity_y;

    double thrust_x;
    double thrust_y;
    bool thrust_on;

    double terminal_velocity;
    double orientation;

    LanderLocationCoords landerSegments[MAX_SHAPE_SEGMENTS];
    int segmentCount;
};


/* Function prototypes.
 * Please see ./gamestate.c for more information. */

void setLanderMask ( void );
void* getLanderMask ( void );

void initLandersHash ( void );
LanderFigure* newLander ( char * name, double side_length,
                          double x_offset, double y_offset );
void initLanderFigure ( LanderFigure * lander );
void addLander ( char * name, LanderFigure * lander );

void updateLander ( char * name, double x_shift, double y_shift,
                    int rotate_direction );
void drawLander ( LanderFigure * lander );
void eraseLander ( LanderFigure * lander );
void rotateLander ( LanderFigure * baseLander, LanderFigure * lander,
                    int rotate_direction );

double landerComputeVerticalVelocity ( LanderFigure * lander );
double landerComputeHorizontalVelocity ( LanderFigure * lander );
void landerComputeThrust ( char * name );


void landerTimeStep ( int sig );

/* Prototype for Darel Rex Finley line segment intersection function. */
bool lineSegmentIntersection(
double Ax, double Ay,
double Bx, double By,
double Cx, double Cy,
double Dx, double Dy,
double *X, double *Y);


void landerDrawThrust ( char * name );
void landerEraseThrust ( char * name );
void landerActivateThrustFlag ( char * name );
void landerComputeBounce ( LanderFigure * lander );
void landerComputeWrap ( char * name );

void setLandscape ( struct worldLandscape * landscape );
void drawLandscape ( void );
void setGravity ( double gravity );
void setThrust ( double thrust );

void setBounce ( bool value );
void setWrap ( bool value );
int getPressedKey ( void );
int getLandingStatus ( void );

//void destroyLanders ( void );

#endif /* end of include guard: GAMESTATE */
